<template>
  <div :class="['my-tags', appStore.isDeep ? 'deep' : 'light']">
    <div
      v-for="item in state.list"
      :key="item[valueKey]"
      :class="[
        'item',
        (selects || []).includes(item[valueKey]) ? 'active' : '',
        onlySelect ? 'only' : '',
      ]"
      :style="{ cursor: disabled ? 'not-allowed' : 'pointer' }"
      @click="() => methods.handleClick(item)"
    >
      {{ item[labelKey] }}
    </div>
  </div>
</template>
<script setup lang="jsx">
import { useAppStore } from '@/store'
import { isEqual, cloneDeep, debounce } from 'lodash-es'
defineOptions({
  name: 'MyTags',
})
const appStore = useAppStore()
const props = defineProps({
  options: {
    type: [Array, Function],
    default: () => [],
  },
  labelKey: {
    type: String,
    default: 'label',
  },
  valueKey: {
    type: String,
    default: 'value',
  },
  disabled: {
    type: Boolean,
    default: false,
  },
  resolveFn: {
    type: Boolean,
    default: true,
  },
  extraParams: {
    type: Object,
    default: () => ({}),
  },
  onlySelect: {
    type: Boolean,
    default: false,
  },
  autoSelectAll: {
    type: Boolean,
    default: false,
  },
  autoInitOptions: {
    type: Boolean,
    default: true,
  },
  changeWait: {
    type: Number,
    default: 300,
  },
})
const emits = defineEmits(['updateModelValue', 'changeExtraParams', 'asyncLoad'])
const selects = defineModel({
  type: Array,
  default: () => [],
})
const state = reactive({
  list: [],
})
const methods = reactive({
  async initOptions() {
    if (Array.isArray(props.options)) {
      state.list = props.options
    } else if (typeof props.options === 'function') {
      if (props.resolveFn) {
        const { data } = await props.options(props.extraParams)
        state.list = data
      } else {
        state.list = await props.options(props.extraParams)
      }
      if (props.autoSelectAll) {
        if (!selects.value || !selects.value.length) {
          selects.value = state.list.map((item) => item[props.valueKey])
        }
      }
      emits('asyncLoad', state.list)
    }
  },
  handleClick(current) {
    if (props.disabled) return
    if (selects.value.includes(current[props.valueKey])) {
      const index = selects.value.findIndex((item) => {
        return item === current[props.valueKey]
      })
      selects.value.splice(index, 1)
    } else {
      selects.value.push(current[props.valueKey])
    }
    emits('updateModelValue', selects.value)
  },
})
onBeforeMount(() => {
  if (props.autoInitOptions) {
    methods.initOptions()
  }
})

watch(
  () => props.options,
  () => {
    methods.initOptions()
  },
  {
    deep: true,
  }
)
const handleChange = debounce(() => {
  emits('changeExtraParams')
  methods.initOptions()
}, props.changeWait)
watch(
  () => cloneDeep(props.extraParams),
  (newVal, oldVal) => {
    if (!isEqual(newVal, oldVal)) {
      handleChange()
    }
  },
  {
    deep: true,
  }
)
</script>
<style lang="scss" scoped>
.my-tags {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  .item {
    box-sizing: border-box;
    user-select: none;
    flex-shrink: 0;
    font-size: 14px;
    padding: 0 12px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    // border: 1px solid #d9dee9;
    // color: #6c687c;
    // background: #fff;
    font-weight: 400;
    &.active {
      border-color: rgba(109, 97, 227, 0.08);
      color: #6d61e3;
      background: rgba(109, 97, 227, 0.1);
      font-weight: 500;
    }
    &.only {
      display: none;
    }
    &.active.only {
      display: flex;
      // background: rgba(155, 164, 178, 0.1);
      // border-color: rgba(155, 164, 178, 0.1);
      // color: #37383a;
    }
  }
  &.light {
    .item {
      border: 1px solid #d9dee9;
      color: #6c687c;
      background: #fff;
      border-radius: 4px;
      &.active {
        border-color: rgba(109, 97, 227, 0.08);
        color: #6d61e3;
        background: rgba(109, 97, 227, 0.1);
      }
    }
  }
  &.deep {
    .item {
      border: 1px solid #2ba1ff4d;
      color: #2ba1ff;
      &.active {
        border-color: rgba(81, 230, 251, 0.15);
        color: #51e6fb;
        background: rgba(81, 230, 251, 0.1);
      }
    }
  }
}
</style>
